# -*- coding: UTF-8 -*-
# __author__ = '10459'
from flask import current_app
from sqlalchemy import Column, Integer, String, Boolean, Float
from app.libs.enums import PendingStatus
from app.libs.helper import is_isbn_or_key
from app.models.base import Base, db
from werkzeug.security import generate_password_hash,check_password_hash
from flask_login import UserMixin
from app import login_manager
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from app.models.drift import Drift
from app.models.gift import Gift
from app.models.wish import Wish
from app.spider.yushu_book import YuShuBook
from math import floor

#为了使用flask-login，需要模板继承UserMixin里面好多方法如get_id
class User(UserMixin,Base):
    # __tablename__='USER'#更改表名为自己想要的，默认为类名
    id = Column(Integer, primary_key=True)
    nickname = Column(String(24), nullable=False)  # nullable不允许为空
    phone_number = Column(String(18), unique=True)
    email = Column(String(50), nullable=False, unique=True)
    comfirmed = Column(Boolean, default=False)
    beans = Column(Float, default=0)   #鱼豆，交易使用的
    send_counter = Column(Integer, default=0)
    receive_counter = Column(Integer, default=0)
    _password = Column('password',String(128),nullable=False)
    wx_open_id = Column(String(50))# 微信开发小程序使用
    wx_name = Column(String(50))#  微信开发小程序使用

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self,raw):
        self._password=generate_password_hash(raw)
    #实例可以访问类属性
    def can_send_drift(self):
        if self.beans<1:
            return False
        success_gift_count= Gift.query.filter_by(uid= self.id,launched = True).count()
        #2不能写数字，用枚举
        success_receive_count= Drift.query.filter_by(requester_id=self.id,
                                                     pending = PendingStatus.Success).count()
        #每赠送出两本书就可以索要1本书，floor就是取整，1.5就是1,2.9=1
        return True if floor(success_receive_count/2)<=floor(
            success_gift_count) else False

    def check_password(self,raw):
        return check_password_hash(self._password,raw)   #先将raw加密，然后与self._password
    def can_save_to_list(self,isbn):
        if is_isbn_or_key(isbn) != 'isbn':
            return False
        yushu_book = YuShuBook()
        yushu_book.search_by_isbn(isbn)
        if not yushu_book.first:
            return False
        #不允许一个用户同时赠送多本相同的图书
        #一个用户不能同时成为赠送者与索要者
        #换句话说既不在赠送清单也不再索要清单中才能添加
        gifting= Gift.query.filter_by(uid=self.id,isbn=isbn,launched=False).first()
        wishing= Wish.query.filter_by(uid=self.id,isbn=isbn,launched=False).first()
        if not gifting and not wishing:
            return True
        else:
            return False
    #expiration单位是s，加密,实例可以访问类变量,SECRET_KEY秘钥。Serializer序列化随机东西，然后需要key解码
    def generate_token(self,expiration=600):
        s = Serializer(current_app.config['SECRET_KEY'],expiration)
        temp=s.dumps({"id":self.id}).decode('UTF-8')
        return temp
    @staticmethod
    def reset_password(token,new_password):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data=s.loads(token.encode('UTF-8'))
        except:
            return False
        uid = data.get('id')
        with db.auto_commit():
            user = User.query.get(uid)
            user.password=new_password
        return True
    @property
    def Summary(self):
        return dict(
            nickname=self.nickname,
            beans = self.beans,
            email = self.email,
            send_receive = str(self.send_counter)+'/'+str(self.receive_counter)
            )



    # def get_id(self):
    #     return self.id
@login_manager.user_loader
def get_user(uid):
    return User.query.get(int(uid))    #不用filter_by因为是访问主键可以用get

